package com.test;

import java.io.File;
import java.io.FileInputStream;
import java.lang.instrument.ClassDefinition;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.security.ProtectionDomain;

public class Agent {

	public static void agentmain(String agentArgs, Instrumentation inst)
			throws UnmodifiableClassException {
	}

	public static void premain(String agentArgs, Instrumentation inst)
			throws UnmodifiableClassException {
		inst.addTransformer(new ClassReplaceTransformer(), true);
		
		final Instrumentation i = inst;
		Thread thread = new Thread(new Runnable() {

			@Override
			public void run() {
				try { Thread.sleep(2000); } catch (InterruptedException e) {}
				try {
					i.retransformClasses(Class.forName("com.test.agent.TestRetransform"));
					//ClassDefinition cd = new ClassDefinition(Class.forName("com.test.agent.Test"), new byte[]{1});
					//i.redefineClasses(cd);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}});
		thread.start();
	}
}



class ClassReplaceTransformer implements ClassFileTransformer {

	@Override
	public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
			ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {

		if(className.equals("com/test/agent/TestRetransform") && classBeingRedefined == null) {
			System.out.println("agent:loading class TestRetransform");
			System.out.println("agent:orginal bytes : " + classfileBuffer.length);
			return null;	
		}
		
		if(className.equals("com/test/agent/TestRetransform") && classBeingRedefined != null) {
			System.out.println("agent:retransform class TestRetransform");
			System.out.println("agent:orginal bytes : " + classfileBuffer.length);
			try {
				File f = new File("TestRetransform.class");
				byte[] bytes = new byte[(int)f.length()];
				new FileInputStream(f).read(bytes);
				System.out.println("agent:new bytes : " + bytes.length);
				return bytes;
			} catch (Exception e) {
				e.printStackTrace();
			}		
		}
		return null;
	}
	
}